﻿@{
    ViewBag.Title = "Index";
    Layout = null;
}

<!--http://net.tutsplus.com/tutorials/javascript-ajax/build-a-contacts-manager-using-backbone-js-part-4/-->

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Backbone.js Web App</title>
        <style type="text/css">
            #contacts { width:1200px; margin:auto; }
            .contact-container { width:360px; padding:10px; border:1px solid #aaa; margin:0 10px 10px 0; position:relative; float:left; font-family:sans-serif; color:#333; background-color:#eee; }
            .contact-container h1 { margin:0; font-weight:normal; }
            .contact-container h1 span { float:right; font-size:14px; line-height:24px; font-weight:normal; }
            .contact-container img { border-width:1px; border-style:solid; border-color:#fff; border-right-color:#aaa; border-bottom-color:#aaa; margin-right:10px; float:left; }
            .contact-container div { margin-bottom:24px; font-size:14px; }
            .contact-container a { color:#333;}
            .contact-container dl { margin:0; float:left; font-size:14px; }
            .contact-container dt, .contact-container dd { margin:0; float:left; }
            .contact-container dt { width:50px; clear:left; }
            .contact-container button { margin-top:10px; float:right; }

            header { margin-bottom:10px; }
            header:after { content:""; display:block; height:0; visibility:hidden; clear:both; font-size:0; line-height:0; }

            #filter { float:left; }
            #showForm { float:right; }
            #addContact { display:none; width:466px; float:right; clear:both; font-family:sans-serif; font-size:14px; }
            #addContact label { width:60px; margin-right:10px; text-align:right; line-height:25px; }
            #addContact label, #addContact input { display:block; margin-bottom:10px; float:left; }
            #address { width:380px; margin-left:2px; }
            #addContact label[for="name"], #addContact label[for="address"], #addContact label[for="tel"] { clear:both; }
            #addContact button { display:block; margin:10px 10px 0 0; float:right; clear:both; }
        </style> 
    </head>
<body>
    <h2>Index</h2>
    <div id="contacts">
        <header>
            <div id="filter"><label>Show me:</label></div>
            <a id="showForm" href="#">Add new contact</a>
        </header>
        <form id="addContact" action="#">
            <label for="photo">photo:</label><input id="photo" type="file" />
            <label for="type">Type:</label><input id="type" />
            <label for="name">Name:</label><input id="name" />
            <label for="address">Address:</label><input id="address" />
            <label for="tel">Tel:</label><input id="tel" />
            <label for="email">Email:</label><input id="email" />
            <button id="add">Add</button>
        </form>
    </div>

    <script id="contactTemplate" type="text/template">
        <img src="{{ photo }}" alt="{{ name }}" />
        <h1>{{ name }}<span>{{ type }}</span></h1>
        <div>{{ address }}</div>
        <dl>
            <dt>Tel:</dt><dd>{{ tel }}</dd>
            <dt>Email:</dt><dd><a href="mailto:{{ email }}">{{ email }}</a></dd>
        </dl>
        <button class="delete">Delete</button>
        <button class="edit">Edit</button>
    </script>

    <script id="contactEditTemplate" type="text/template">
        <form action="#">
            <input type="file" value="{{ photo }}" />
            <input class="name" value="{{ name }}" />
            <input id="type" type="hidden" value="{{ type }}" />
            <input class="address" value="{{ address }}" />
            <input class="tel" value="{{ tel }}" />
            <input class="email" value="{{ email }}" />
            <button class="save">Save</button>
            <button class="cancel">Cancel</button>
        </form>
    </script>

    <script src="~/Scripts/jquery-1.9.1.js"></script>
    <script src="~/Scripts/libs/backbone/mustache.js"></script>
    <script src="~/Scripts/libs/backbone/underscore.js"></script>
    <script src="~/Scripts/libs/backbone/backbone.js"></script>

    <script type="text/javascript">
        
        (function ($) {
            var contactsData = [
                { name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
                { name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
                { name: "Contact 3", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
                { name: "Contact 4", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
                { name: "Contact 5", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" }
            ];

            var Contact = Backbone.Model.extend({
                defaults: {
                    photo: "/Images/def_usr.png"
                }
            });

            var Directory = Backbone.Collection.extend({
                model: Contact
            });

            var ContactView = Backbone.View.extend({
                tagName: "article",
                className: "contact-container",
                template: $("#contactTemplate").html(),
                editTemplate: $("#contactEditTemplate").html(),
                events: {
                    "click button.delete": "deleteContact",
                    "click button.edit": "editContact",
                    "change select.type": "addType",
                    "click button.save": "saveEdits",
                    "click button.cancel": "cancelEdit"
                },
                render: function () {
                    var tmpl = Mustache.to_html(this.template, this.model.toJSON());
                    this.$el.html(tmpl);
                    
                    return this;
                },
                deleteContact: function () {
                    var removedType = this.model.get("type").toLowerCase();
                    this.model.destroy();

                    this.remove();

                    if (_.indexOf(directory.getTypes(), removedType) === -1) {
                        directory.$el.find("#filter select").children("[value='" + removedType + "']").remove();
                    }
                },
                editContact: function () {
                    var tmpl = Mustache.to_html(this.editTemplate, this.model.toJSON());
                    this.$el.html(tmpl);

                    var newOpt = $("<option/>", {
                        html: "<em>Add new...</em>",
                        value: "addType"
                    });

                    this.select = directory.createSelect().addClass("type")
                        .val(this.$el.find("#type").val()).append(newOpt)
                        .insertAfter(this.$el.find(".name"));

                    this.$el.find("input[type='hidden']").remove();
                },
                addType: function () {
                    if (this.select.val() === "addType") {
                        this.select.remove();

                        $("<input />", {
                            "class": "type"
                        }).insertAfter(this.$el.find(".name")).focus();
                    }
                },
                saveEdits: function (e) {
                    e.preventDefault();

                    var formData = {},
                        prev = this.model.previousAttributes();

                    $(e.target).closest("form").find(":input").add(".photo").each(function () {
                        var el = $(this);
                        formData[el.attr("class")] = el.val();
                    });

                    if (formData.photo === "") {
                        delete formData.photo;
                    }

                    this.model.set(formData);

                    this.render();

                    if (prev.photo == "/Images/def_usr.png") {
                        delete prev.photo;
                    }

                    _.each(contactsData, function (contact) {
                        if (_.isEqual(contact, prev)) {
                            contactsData.splice(_.indexOf(contactsData, contact), 1, formData);
                        }
                    });
                },
                cancelEdit: function () {
                    this.render();
                }
            });

            var DirectoryView = Backbone.View.extend({
                el: $("#contacts"),
                initialize: function () {
                    this.collection = new Directory(contactsData);
                    this.render();

                    this.$el.find("#filter").append(this.createSelect());

                    this.on("change:filterType", this.filterByType, this);
                    this.collection.on("reset", this.render, this);
                    this.collection.on("add", this.renderContact, this);
                    this.collection.on("remove", this.removeContact, this);
                },
                events: {
                    "change #filter select": "setFilter",
                    "click #add": "addContact",
                    "click #showForm": "showForm"
                },
                render: function () {
                    var me = this;
                    this.$el.find("article").remove();

                    _.each(this.collection.models, function (item) {
                        me.renderContact(item);
                    }, this);
                },
                renderContact: function (item) {
                    var contactView = new ContactView({
                        model: item
                    });
                    this.$el.append(contactView.render().el);
                },
                getTypes: function () {
                    return _.uniq(this.collection.pluck("type"), false, function (type) {
                        return type.toLowerCase();
                    });
                },
                createSelect: function () {
                    var filter = this.$el.find("#filter"),
                        select = $("<select/>", {
                            html: "<option value='all'>All</option>"
                        });

                    _.each(this.getTypes(), function (item) {
                        var option = $("<option/>", {
                            value: item.toLowerCase(),
                            text: item.toLowerCase()
                        }).appendTo(select);
                    });
                    return select;
                },
                setFilter: function (e) {
                    this.filterType = e.currentTarget.value;
                    this.trigger("change:filterType");
                },
                filterByType: function () {
                    if (this.filterType === "all") {
                        this.collection.reset(contactsData);
                    } else {
                        this.collection.reset(contactsData, { silent: true });
                        var filterType = this.filterType,
                            filtered = _.filter(this.collection.models, function (item) {
                                return item.get("type") === filterType;
                            });
                        this.collection.reset(filtered);
                    }
                    contactsRouter.navigate("filter/" + this.filterType);
                },
                addContact: function (e) {
                    e.preventDefault();
                    var formData = {};

                    $("#addContact").children("input").each(function (i, el) {
                        if ($(el).val() !== "") {
                            formData[el.id] = $(el).val();
                        }
                    });
                    contactsData.push(formData);
                    if (_.indexOf(this.getTypes(), formData.type) === -1) {
                        this.$el.find("#filter").find("select").remove().end().append(this.createSelect());
                    }

                    this.collection.add(new Contact(formData));
                },
                removeContact: function (removedModel) {
                    var removed = removedModel.attributes;

                    if (removed.photo === "/Images/def_usr.png") {
                        delete removed.photo;
                    }

                    _.each(contactsData, function (contact) {
                        if (_.isEqual(contact, removed)) {
                            contactsData.splice(_.indexOf(contactsData, contact), 1);
                        }
                    });
                },
                showForm: function () {
                    this.$el.find("#addContact").slideToggle();
                }
            });

            var ContactsRouter = Backbone.Router.extend({
                routes: { "filter/:type": "urlFilter" },
                urlFilter: function (type) {
                    directory.filterType = type;
                    directory.trigger("change:filterType");
                }
            });

            var directory = new DirectoryView();

            var contactsRouter = new ContactsRouter();

            Backbone.history.start();

        }(jQuery));

    </script>
    </body>
</html>